#ifndef _AVR_ADC_H_
#define _AVR_ADC_H_

#include "../../Component.h"
#include<avr/io.h>
#include<avr/interrupt.h>
#include "../../../bit/bit.h"

namespace Hardware
{
namespace Avr
{

	typedef struct ADC_CONFIG
	{
		unsigned char voltRef : 2;
		unsigned char leftAdjust : 1;
		unsigned char enable : 1;
		unsigned char startConversion : 1;
		unsigned char autoTrigger : 1;
		unsigned char prescaler;
		unsigned char triggerSource;
		unsigned char interrupt : 1;
		unsigned char analogSelect : 5;
	} AdcConfig;

	typedef struct ADC_DATA
	{
		unsigned long data;
	} AdcData;

	class Adc : public Component<AdcConfig, AdcData>
	{
		public :
		enum VoltageReferenceSelection
		{
			AREF_Internal_Vref_Off=0x00,
			AVCC_external_cap_at_AREF=0x01,
			ADC_RESERVED=0x02,
			Internal_2_56VRef_ext_cap=0x03
		};
		enum Prescaler
		{
			Prescale2_1 = 0x00,
			Prescale2_2 = 0x01,
			Prescale_4 = 0x02,
			Prescale_8 = 0x03,
			Prescale_16 = 0x04,
			Prescale_32 = 0x05,
			Prescale_64 = 0x06,
			Prescale_128 = 0x07
		};
		enum AutoTriggerSource
		{
			FreeRunning = 0x00,
			AnalogComparator = 0x01,
			ExternalInterruptRequest0 = 0x02,
			Timer0_CompareMatch = 0x03,
			Timer0_Overflow = 0x04,
			Timer1_CampareMatchB = 0x05,
			Timer1_Overflow = 0x06,
			Timer1_CaptureEvent = 0x07
		};

		Adc(){}
		Adc(AdcConfig c){configuration=c;}
		void config()
		{
			//set voltage reference.
			ADMUX = SetBit(ADMUX, REFS0, 
				GetBit(configuration.voltRef,0));
			ADMUX = SetBit(ADMUX, REFS1, 
				GetBit(configuration.voltRef,1));
			//set left adjust
			ADMUX = SetBit(ADMUX, ADLAR, configuration.leftAdjust);
			//analog select.//sets all bits at once.
			ADMUX = (ADMUX & 0xE0)|(configuration.analogSelect & 0x1F);
			//set ADC enable
			ADCSRA = SetBit(ADCSRA, ADEN, configuration.enable);
			//set start conversion.
			ADCSRA = SetBit(ADCSRA, ADSC, configuration.startConversion);
			//set the auto trigger enable
			ADCSRA = SetBit(ADCSRA, ADATE, configuration.autoTrigger);
			//set interrupt enable
			ADCSRA = SetBit(ADCSRA, ADIE, configuration.interrupt);
			//sets the prescaler
			ADCSRA = (ADCSRA & 0xF8) | configuration.prescaler;
			//set auto trigger source
			SFIOR = (SFIOR & 0xF0) | configuration.triggerSource;
		}
		void run(){}
	};
}
}




#endif
